//
//  DCXMPPTool.m
//  xmppBase
//
//  Created by striby on 16/1/7.
//  Copyright © 2016年 com.dc. All rights reserved.
//

#import "DCXMPPTool.h"
#import <AVFoundation/AVFoundation.h>
@implementation DCXMPPTool
@synthesize xmppStream;
@synthesize xmppRoster;
@synthesize xmppRosterStorage;

@synthesize xmppReconnect;
@synthesize xmppMessageArchivingCoreDataStorage;
@synthesize xmppMessageArchivingModule;

+(DCXMPPTool *)shareInstance
{
    static DCXMPPTool * instance = nil;
    
    static dispatch_once_t once;
    
    dispatch_once(&once, ^{
        instance = [[self alloc]init];
         instance.connectionStatus = XmppConnectionStatusLogin;
        
//        instance.imQue = dispatch_get_global_queue(2, 0);
        instance.imQue = dispatch_get_main_queue();
        
        
        [[NSNotificationCenter defaultCenter]addObserver:instance selector:@selector(newMessageIncoming:) name:kXMPP_MESSAGE_CHANGE object:nil];
        
    });
    
   
    
    return instance;
}


#pragma mark - XMPP

-(void)setupStream{
    
    //初始化XMPPStream
    xmppStream = [[XMPPStream alloc]init];
    xmppStream.enableBackgroundingOnSocket = YES;
    [xmppStream addDelegate:self delegateQueue:self.imQue];
    
    xmppReconnect = [[XMPPReconnect alloc]init];
    [xmppReconnect activate:xmppStream];
    
    
    xmppRosterStorage = [[XMPPRosterCoreDataStorage alloc]init];
    
    
    _xmppRosterMemoryStorage = [[XMPPRosterMemoryStorage alloc] init];
    
    xmppRoster = [[XMPPRoster alloc]initWithRosterStorage:_xmppRosterMemoryStorage];
    [xmppRoster activate:xmppStream];
    
    [xmppRoster addDelegate:self delegateQueue:self.imQue];
    
    xmppMessageArchivingCoreDataStorage = [XMPPMessageArchivingCoreDataStorage sharedInstance];
    xmppMessageArchivingModule = [[XMPPMessageArchiving alloc]initWithMessageArchivingStorage:xmppMessageArchivingCoreDataStorage];
    [xmppMessageArchivingModule setClientSideMessageArchivingOnly:YES];
    [xmppMessageArchivingModule activate:xmppStream];
    [xmppMessageArchivingModule addDelegate:self delegateQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 9)];
    
    
    
    _xmppIncomingFileTransfer = [[XMPPIncomingFileTransfer alloc] initWithDispatchQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)];
    [_xmppIncomingFileTransfer activate:self.xmppStream];
    [_xmppIncomingFileTransfer addDelegate:self delegateQueue:self.imQue];
    [_xmppIncomingFileTransfer setAutoAcceptFileTransfers:YES];
    
    
    _xmppvCardStorage = [XMPPvCardCoreDataStorage sharedInstance];
    
    _xmppvCardTempModule = [[XMPPvCardTempModule alloc] initWithvCardStorage:_xmppvCardStorage];
    
    _xmppvCardAvatarModule = [[XMPPvCardAvatarModule alloc] initWithvCardTempModule:_xmppvCardTempModule];
    
    
    
    [_xmppvCardTempModule addDelegate:self delegateQueue:self.imQue];
    
    [_xmppvCardAvatarModule addDelegate:self delegateQueue:self.imQue];
}

-(void)logoutXmppHost
{
    if (xmppStream.isConnected) {
        
        //生成网络状态
        XMPPPresence *presence = [XMPPPresence presenceWithType:@"unavailable"];
        //改变通道状态
        [self.xmppStream sendElement:presence];
        //断开链接
        
        [xmppStream disconnect];
        

        [[NSNotificationCenter defaultCenter]postNotificationName:kXmppUserLogout object:nil];
    }
    
}

-(BOOL)connectXmppHost{
    
    [self setupStream];
    
    //从本地取得用户名，密码和服务器地址
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    
    NSString * jID = [defaults objectForKey:kMyJID];
    NSString * pass = [defaults objectForKey:kPS];
    
    NSString *userId = [NSString stringWithFormat:@"%@@%@/%@",jID,DomainName,isIPHONE?iPhoneResourceName:iPadResourceName];
    
    
    
    if (![xmppStream isDisconnected]) {
        return YES;
    }
    
    if (userId == nil || pass == nil) {
        return NO;
    }
    
    //设置用户
    [xmppStream setMyJID:[XMPPJID jidWithString:userId]];
    //    //设置服务器
//        [xmppStream setHostName:DomainName];
    //
    //    xmppStream.hostPort = ServerPort;
    
    
    //连接服务器
    NSError *error = nil;
    if (![xmppStream connectWithTimeout:XMPPStreamTimeoutNone error:&error]) {
        
        NSLog(@"connect error:%@",error);
        return NO;
    }
    
    return YES;
    
}

-(void)newMessageIncoming:(NSNotification*)sender
{
    
    XMPPMessage * message = sender.object;
    
    DDXMLElement * messageSender = [[message elementsForName:messageFrom] firstObject];
    
    XMPPJID * senderJid = [XMPPJID jidWithString:[messageSender stringValue]];
    //自己发送的信息
    if ([xmppStream.myJID isEqualToJID:senderJid]) {
        return;
    }

    
    AudioServicesPlaySystemSound(1007);
    
}

#pragma mark - 添加删除用户
-(void)addFriendWithUserJid:(XMPPJID *)jid
{
    XMPPvCardTemp * card = [self.xmppvCardTempModule vCardTempForJID:jid shouldFetch:YES];
    
    [self.xmppRoster addUser:jid withNickname:card.nickname];
}

-(void)deletaFriendWithUserJid:(XMPPJID *)jid
{
    [self.xmppRoster removeUser:jid];
}

#pragma mark - xmppRosterDelegate
- (void)xmppRoster:(XMPPRoster *)sender didReceivePresenceSubscriptionRequest:(XMPPPresence *)presence
{
    self.receivePresence = presence;
    
//    NSString *message = [NSString stringWithFormat:@"【%@】想加你为好友",presence.from.bare];
//    
//    UIAlertAction * cancle = [UIAlertAction actionWithTitle:@"好的" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
//        [self.xmppRoster acceptPresenceSubscriptionRequestFrom:_receivePresence.from andAddToRoster:YES];
//    }];
//    
//    UIAlertController * alert = [UIAlertController alertControllerWithTitle:@"好友请求" message:message preferredStyle:UIAlertControllerStyleAlert];
//    [alert addAction:cancle];
//    
//    [self.window.rootViewController presentViewController:alert animated:YES completion:nil];
    
//    [[NSNotificationCenter defaultCenter]postNotificationName:kFriendShipStatusChanged object:nil];
}

#pragma mark - xmppDelegate

-(void)xmppStreamDidConnect:(XMPPStream *)sender
{
    NSError *error = nil;
    
    //验证帐户密码
    
    
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    
    
    NSString * pass = [defaults objectForKey:kPS];
    
    if (self.connectionStatus==XmppConnectionStatusRegister) {
        __autoreleasing NSError * error;
   
        BOOL result = [sender registerWithPassword:pass error:&error];
        
        if (error) {
            NSLog(@"%@",error);
        }
        
    }
    else
    {
        
        
        BOOL bRes =  [xmppStream authenticateWithPassword:pass error:&error];
    }
    

    
}

-(void)xmppStreamDidRegister:(XMPPStream *)sender
{
    NSLog(@"xmppStreamDidRegister");
    
    [[NSNotificationCenter defaultCenter]postNotificationName:kXmppRegiserSuccessed object:nil];
    
    self.connectionStatus = XmppConnectionStatusLogin;
    
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    
    
    NSString * pass = [defaults objectForKey:kPS];
    __autoreleasing NSError * error;
    BOOL bRes =  [xmppStream authenticateWithPassword:pass error:&error];
}

-(void)xmppStream:(XMPPStream *)sender didNotRegister:(DDXMLElement *)error
{
    NSLog(@"didNotRegister error:%@",error);
    
    [[NSNotificationCenter defaultCenter]postNotificationName:kXmppRegiserFailed object:nil];
    
    self.connectionStatus=XmppConnectionStatusLogin;
    [self connectXmppHost];
}

- (void)xmppStreamDidAuthenticate:(XMPPStream *)sender

{
    
    XMPPPresence *presence = [XMPPPresence presence];
    //可以加上上线状态，比如忙碌，在线等
    [xmppStream sendElement:presence];//发送上线通知

    
    
    [self.xmppRoster activate:self.xmppStream];
    
    [self.xmppRoster addDelegate:self delegateQueue:self.imQue];
    
    [_xmppvCardTempModule activate:self.xmppStream];
    
    [_xmppvCardAvatarModule activate:self.xmppStream];
    

    
    
    
    
    [[NSNotificationCenter defaultCenter]postNotificationName:kLoginAndAuthenticateSuccessed object:nil];
    
  
}

- (void)xmppStream:(XMPPStream *)sender didNotAuthenticate:(NSXMLElement *)error
{
    NSLog(@"error:%@",error);
    
}

- (NSString *)xmppStream:(XMPPStream *)sender alternativeResourceForConflictingResource:(NSString *)conflictingResource
{
    NSLog(@"alternativeResourceForConflictingResource: %@",conflictingResource);
    return isIPHONE?iPhoneResourceName:iPadResourceName;
}
- (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq
{
    NSLog(@"didReceiveIQ: %@",iq.description);
    
    if ([iq isResultIQ]) {
            // 服务器返回是房间信息
        if (iq.childElement) {
            if ([iq.childElement.name isEqualToString:@"query"] &&
                [iq.childElement.xmlns isEqualToString:@"http://jabber.org/protocol/disco#items"]){
                
                NSArray * rooms =  iq.childElement.children;
                
                NSLog(@"%@",rooms);
                
            }
        }
        
    }
    else
    {
        if ([iq.children firstObject]) {
            if ([[[iq.children firstObject] xmlns] isEqualToString:@"jabber:iq:roster"]) {
                
                [[NSNotificationCenter defaultCenter]postNotificationName:kFriendShipStatusChanged object:nil];
            }
        }
      
    }
 
    
    return YES;
}
- (void)xmppStream:(XMPPStream *)sender didReceiveMessage:(XMPPMessage *)message
{
    NSLog(@"didReceiveMessage: %@",message.description);
    //    if ([self.chatDelegate respondsToSelector:@selector(getNewMessage:Message:)]) {
    //        [self.chatDelegate getNewMessage:self Message:message];
    //    }
    
//    if ([self.window.rootViewController.class isSubclassOfClass:[UINavigationController class]]) {
//        UINavigationController * na = self.window.rootViewController;
//        
//        UIViewController * vc = na.viewControllers[0];
//        
//        [DCHUD showInView:vc.view ForText:message.body];
//    }
    
    if ([message.type isEqualToString:@"normal"]) {
        
        if ([message.children firstObject]) {
            
            XMPPElement * element = [message.children firstObject];
            /**
             *  群聊邀请
             */
            if ([element.xmlns isEqualToString:@"http://jabber.org/protocol/muc#user"]) {
                
                XMPPvCardTemp * mycard = [[DCXMPPTool shareInstance].xmppvCardTempModule vCardTempForJID:[DCXMPPTool shareInstance].xmppStream.myJID shouldFetch:YES];
                
                
                [mycard addJoinedGroup:message.from];
                
                [[DCXMPPTool shareInstance].xmppvCardTempModule updateMyvCardTemp:mycard];
                
                [_xmppvCardTempModule updateMyvCardTemp:mycard];
                
                [[DCIMGroupManager shareInstance] joinRoomWithRoomJid:message.from];
                
               
            }
            
        }
        
    }
    
    
    
}
- (void)xmppStream:(XMPPStream *)sender didReceivePresence:(XMPPPresence *)presence
{
    NSLog(@"didReceivePresence: %@",presence.description);
    //用户信息更新
    if ([presence elementForName:@"x"]) {
        if ([[presence elementForName:@"x"].xmlns isEqualToString:@"vcard-temp:x:update"]) {
            if (presence.from&&![presence.from.bare isEqualToString:self.xmppStream.myJID.bare]) {
                NSFetchRequest * fetchRequest = [[NSFetchRequest alloc]initWithEntityName:@"XMPPvCardCoreDataStorageObject"];
                
                fetchRequest.predicate =[NSPredicate predicateWithFormat:@"jidStr = %@",presence.from.bare];
                
                __autoreleasing NSError * error;
                
                NSArray *fetchResult =[self.xmppvCardStorage.mainThreadManagedObjectContext executeFetchRequest:fetchRequest error:&error];
                
                if (!error) {
                    for (XMPPvCardCoreDataStorageObject * item in fetchResult) {
                        [self.xmppvCardStorage.mainThreadManagedObjectContext deleteObject:item];
                    }
                    [self.xmppvCardStorage.mainThreadManagedObjectContext save:&error];
                }
            }
        }
    }
    
    [[NSNotificationCenter defaultCenter]postNotificationName:kFriendShipStatusChanged object:nil];

        if ([presence.from.user isEqualToString:self.xmppStream.myJID.user]&&[presence.to.user isEqualToString:self.xmppStream.myJID.user]) {
            
                      XMPPvCardTemp * mycard = [[DCXMPPTool shareInstance].xmppvCardTempModule myvCardTemp];
 
            
            //群组存储
            for (DDXMLElement * group in [mycard getCreatedGroup]) {
                //
                        [[DCIMGroupManager shareInstance]joinRoomWithRoomJid:[XMPPJID jidWithString:[group stringValue]]];
            }
            
            //群组存储
            for (DDXMLElement * group in [mycard getJoinedGroup]) {
                //
                [[DCIMGroupManager shareInstance]joinRoomWithRoomJid:[XMPPJID jidWithString:[group stringValue]]];
            }
            
            
            
            //如果有注册信息 将信息更新
            if (self.userinfo) {
                
                
                DDXMLElement * tele = [[DDXMLElement alloc]initWithName:@"tel" stringValue:[self.userinfo objectForKey:kUserTelephoneNum]];
                
                
                mycard.nickname = [self.userinfo objectForKey:kUserNickName];
                
                [mycard addChild:tele];
                
                if ([self.userinfo objectForKey:kUserEmail]) {
                    DDXMLElement * email = [[DDXMLElement alloc]initWithName:@"email" stringValue:[self.userinfo objectForKey:kUserEmail]];
                    [mycard addChild:email];
                }
                
                if ([self.userinfo objectForKey:kUserGender]) {
                    DDXMLElement * gender = [[DDXMLElement alloc]initWithName:@"gender" stringValue:[self.userinfo objectForKey:kUserGender]];
                
                    
                    [mycard addChild:gender];
                }
                
                if (mycard) {
                     [[DCXMPPTool shareInstance].xmppvCardTempModule updateMyvCardTemp:mycard];
                     self.userinfo=nil;
                }
                
               
            }
            
            [[NSNotificationCenter defaultCenter]postNotificationName:kXmppMyInfoChanged object:nil];
            
        }
    
}
- (void)xmppStream:(XMPPStream *)sender didReceiveError:(NSXMLElement *)error
{
    NSLog(@"didReceiveError: %@",error.description);
}
- (void)xmppStream:(XMPPStream *)sender didSendIQ:(XMPPIQ *)iq
{
    NSLog(@"didSendIQ:%@",iq.description);
}
- (void)xmppStream:(XMPPStream *)sender didSendMessage:(XMPPMessage *)message
{
    NSLog(@"didSendMessage:%@",message.description);
}
- (void)xmppStream:(XMPPStream *)sender didSendPresence:(XMPPPresence *)presence
{
    NSLog(@"didSendPresence:%@",presence.description);
}
- (void)xmppStream:(XMPPStream *)sender didFailToSendIQ:(XMPPIQ *)iq error:(NSError *)error
{
    NSLog(@"didFailToSendIQ:%@",error.description);
}
- (void)xmppStream:(XMPPStream *)sender didFailToSendMessage:(XMPPMessage *)message error:(NSError *)error
{
    NSLog(@"didFailToSendMessage:%@",error.description);
}
- (void)xmppStream:(XMPPStream *)sender didFailToSendPresence:(XMPPPresence *)presence error:(NSError *)error
{
    NSLog(@"didFailToSendPresence:%@",error.description);
}
- (void)xmppStreamWasToldToDisconnect:(XMPPStream *)sender
{
    NSLog(@"xmppStreamWasToldToDisconnect");
}
- (void)xmppStreamConnectDidTimeout:(XMPPStream *)sender
{
    NSLog(@"xmppStreamConnectDidTimeout");
}
- (void)xmppStreamDidDisconnect:(XMPPStream *)sender withError:(NSError *)error
{
    NSLog(@"xmppStreamDidDisconnect: %@",error.description);
}

- (void)xmppvCardTempModule:(XMPPvCardTempModule *)vCardTempModule
        didReceivevCardTemp:(XMPPvCardTemp *)vCardTemp
                     forJID:(XMPPJID *)jid
{
    [[NSNotificationCenter defaultCenter]postNotificationName:kXmppUserInfoGetSuccessed object:nil];
}

#pragma mark ===== 文件接收=======
/** 是否同意对方发文件给我 */
- (void)xmppIncomingFileTransfer:(XMPPIncomingFileTransfer *)sender didReceiveSIOffer:(XMPPIQ *)offer
{
    NSLog(@"%s",__FUNCTION__);
    //弹出一个是否接收的询问框
    //        [self.xmppIncomingFileTransfer acceptSIOffer:offer];
    
}

- (void)xmppIncomingFileTransfer:(XMPPIncomingFileTransfer *)sender didSucceedWithData:(NSData *)data named:(NSString *)name
{
    XMPPJID *jid = [sender getSenderJID];
    NSLog(@"%s",__FUNCTION__);
    //在这个方法里面，我们通过带外来传输的文件
    //因此我们的消息同步器，不会帮我们自动生成Message,因此我们需要手动存储message
    //根据文件后缀名，判断文件我们是否能够处理，如果不能处理则直接显示。
    //图片 音频 （.wav,.mp3,.mp4)
    NSString *extension = [name pathExtension];
    if (![@"wav" isEqualToString:extension]) {
        return;
    }
    //创建一个XMPPMessage对象,message必须要有from
    XMPPMessage *message = [XMPPMessage messageWithType:@"chat" to:jid];
    //将这个文件的发送者添加到Message的from
    [message addAttributeWithName:@"from" stringValue:[sender getSenderJID].bare];
    [message addSubject:@"audio"];
    
    //保存data
    NSString *path =  [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    path = [path stringByAppendingPathComponent:[XMPPStream generateUUID]];
    path = [path stringByAppendingPathExtension:@"wav"];
    [data writeToFile:path atomically:YES];
    
    [message addBody:path.lastPathComponent];
    
    [self.xmppMessageArchivingCoreDataStorage archiveMessage:message outgoing:NO xmppStream:self.xmppStream];
}
#pragma mark - XMPPReconnectDelegate
- (void)xmppReconnect:(XMPPReconnect *)sender didDetectAccidentalDisconnect:(SCNetworkReachabilityFlags)connectionFlags
{
    NSLog(@"didDetectAccidentalDisconnect:%u",connectionFlags);
}
- (BOOL)xmppReconnect:(XMPPReconnect *)sender shouldAttemptAutoReconnect:(SCNetworkReachabilityFlags)reachabilityFlags
{
    NSLog(@"shouldAttemptAutoReconnect:%u",reachabilityFlags);
    return YES;
}




@end
